/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package researchgrants.parts.GrantRequest.nsfcode;

import researchgrants.parts.LoggedData.LoggedDataOutSerializable;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.LinkedList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import researchgrants.parts.LoggedData.panels.trees.TreeableLoggedData;
import researchgrants.parts.db.Db;

/**
 * Represent an NsfCode, which is a field within a GrantRequest.
 * 
 * The class is LoggedDataOutSerializable to allow it to be saved implicitly through panels
 * The class is TreeableLoggedData to allow it to populate tree navigators (LoggedDataPanelsTree)
 * @author DOStudent1
 */
public class NsfCode implements LoggedDataOutSerializable, TreeableLoggedData{

    // the root of tree. Should be in accrodance with the database
    private static final int TopMostNsfCodeId=-1;

    
    public static NsfCode getByNsfCodeId(int nsfCodeId) {
        return(new NsfCode(nsfCodeId));
    }

    /////////////////////////////
    // The fields of NsfCode
    /////////////////////////////

    private String nsfCodeName;
    private int nsfCodeId;
//    private int parentNsfCodeId;

    // private constructor
    private NsfCode(int nsfCodeId) {
        this.nsfCodeId=nsfCodeId;
        syncDataFromDb();
    }

    // populate the fields from the database 
    private void syncDataFromDb() {
        if (nsfCodeId!=TopMostNsfCodeId) {
            // the top most nsf code is a sentry for the non-existing tree root
            try {
                Connection conn=Db.openDbConnection();
                PreparedStatement stat = Db.createPreparedStatement(conn, "SELECT NsfCodeText FROM tblNsfCodes Where NsfCodeId=?");
                stat.setInt(1, nsfCodeId);
                stat.executeQuery();
                ResultSet rs=stat.getResultSet();
                Db.moveToFirstLine(rs);

                nsfCodeName=(String) Db.getColumn(rs, 1);

                rs.close();
                stat.close();
                Db.closeDbConnection(conn);

            } catch (SQLException ex) {
                Logger.getLogger(NsfCode.class.getName()).log(Level.SEVERE, null, ex);
            } catch (Exception ex) {
                throw new IllegalArgumentException("Problem with Data: " + ex.getLocalizedMessage());
            }
        }
    }

    @Override
    public boolean equals(Object obj) {
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        final NsfCode other = (NsfCode) obj;
        return (this.nsfCodeId==other.nsfCodeId);
    }

    @Override
    public int hashCode() {
        int hash = 5;
        hash = 29 * hash + this.nsfCodeId;
        return hash;
    }

    ////////////////////////////////////////
    // allows access to the fields' values
    ////////////////////////////////////////

    public int getNsfCodeId() {
        return(nsfCodeId);
    }
    
    public String getNsfCodeName() {
        return(nsfCodeName);
    }
    
    
    // Serializable like methods for LoggedData
    @Override
    public String toLoggedData() {
        return(Integer.toString(nsfCodeId));
    }
    
    public static NsfCode fromLoggedData(String loggedData) {
        return(NsfCode.getByNsfCodeId(Integer.parseInt(loggedData)));
    }

    // Serializable like methods for LoggedData trees
    @Override
    public String toTreeValue() {
        return(nsfCodeName);
    }

    @Override
    public String toTreeId() {
        return(Integer.toString(nsfCodeId));
    }

    
//    public TreeableLoggedData getParent() {
//        return(getByNsfCodeId(parentNsfCodeId));
//    }
//    

    
    //////////////////////////////////////////////////////////////////////////////////
    // Methods that will help to construct the tree in LoggedDataPanelsListNsfCode
    //////////////////////////////////////////////////////////////////////////////////
    
    // allows to get the root of all nsf codes
    static NsfCode getTopMostNsfCode() {
        return(getByNsfCodeId(TopMostNsfCodeId));
    }

    // allows to get the sons of the current nsf code
    List<TreeableLoggedData> getSons() {
        List<TreeableLoggedData> sons=new LinkedList<TreeableLoggedData>();
        try {
            Connection conn=Db.openDbConnection();
            PreparedStatement stat = Db.createPreparedStatement(conn, "SELECT NsfCodeId FROM tblNsfCodes Where ParentNsfCodeId=? ORDER BY NsfCodeId");
            stat.setInt(1, nsfCodeId);
            stat.executeQuery();
            ResultSet rs=stat.getResultSet();
            while(rs.next()) {
                int sonId=(Integer) Db.getColumn(rs, 1);
                sons.add(NsfCode.getByNsfCodeId(sonId)) ;
            }
            
            rs.close();
            stat.close();
            Db.closeDbConnection(conn);
            
        } catch (SQLException ex) {
            Logger.getLogger(NsfCode.class.getName()).log(Level.SEVERE, null, ex);
        } catch (Exception ex) {
            throw new IllegalArgumentException("Problem with Data: " + ex.getLocalizedMessage());
        }
        return(sons);
    }

}
